# -*- coding: utf-8 -*-

'''
Moduł zawierający widget umożliwiający zdefiniowanie macierzy podobieństw przez użytkownika.
'''

from PyQt4 import QtGui
from PyQt4.QtCore import QString, SIGNAL, Qt
import numpy as np
import copy
import kernel.MatrixParser as mp

##Widget umożliwiający zdefiniowanie macierzy podobieństw przez użytkownika
class UserMatrixWidget(QtGui.QWidget):
    ##Konstruktor klasy
    #@param symbolsList lista nukleotydów
    #@param matrixMinVal minimalna wartość możliwa do ustawienia w komórce macierzy
    #@param matrixMaxVal maksymalna wartość możliwa do ustawienia w komórce macierzy
    #@param parent rodzic obiektu
    def __init__(self, symbolsList, matrixMinVal, matrixMaxVal, parent = None):
        QtGui.QWidget.__init__(self, parent)
        
        self.gridLayout = QtGui.QGridLayout(self)

        self.symbolsList = symbolsList
        self.dim = len(symbolsList)-1
        self.matrix = np.zeros(shape=(self.dim+1, self.dim+1))
        self.spinBoxMat = [[QtGui.QDoubleSpinBox(self) for x in range(self.dim)[y:]] for y in range(self.dim)]
        self.loadFileButton = QtGui.QPushButton('Load file', self)
        self.connect(self.loadFileButton, SIGNAL("clicked()"), self.openMatrixFile)
        
        self.gridLayout.addWidget(self.loadFileButton, 0, 0, Qt.AlignCenter)
       
        for i in range(self.dim):
            self.gridLayout.addWidget(QtGui.QLabel(QString(symbolsList[i]), self), i+1, 0, Qt.AlignCenter)
            self.gridLayout.addWidget(QtGui.QLabel(QString(symbolsList[i]), self), 0, i+1, Qt.AlignCenter)
        
        #inicializacja QDoubleSpinBoxów w które wpisywane są wartości
        for y in range(self.dim):
            for x in range(self.dim)[y:]:
                self.spinBoxMat[y][x-y].setMinimum(matrixMinVal)
                self.spinBoxMat[y][x-y].setMaximum(matrixMaxVal)
                self.spinBoxMat[y][x-y].setDecimals(1)
                self.spinBoxMat[y][x-y].setValue(self.matrix[y][x])
                
                self.spinBoxMat[y][x-y].setButtonSymbols(QtGui.QDoubleSpinBox.NoButtons)
                self.gridLayout.addWidget(self.spinBoxMat[y][x-y], y+1, x+1)
             
    ##Funkcja zwracająca ustawioną przez użytkownika macierz
    #@return macierz ustawiona przez użytkownika   
    def getMatrix(self):
        for y in range(self.dim):
            for x in range(self.dim)[y:]:
                self.matrix[y][x] = self.matrix[x][y] = self.spinBoxMat[y][x-y].value()
        return copy.copy(self.matrix)
             
    ##Funkcja odtwarzająca prawidłową wartość macierzy po pojawieniu się widgetu.   
    def recoverMatrix(self):
        for y in range(self.dim):
            for x in range(self.dim)[y:]:
                self.spinBoxMat[y][x-y].setValue(self.matrix[y][x])
    
    ##Funkcja ustawiająca widget na podaną macierz
    #@param matrix macierz, która ma zostać ustawiona w widgecie 
    def fillMatrix(self, matrix):
        for y in range(self.dim):
            for x in range(self.dim)[y:]:
                self.spinBoxMat[y][x-y].setValue(matrix[y][x])
                
    ##Funkcja powodująca odczytanie z pliku macierzy podobieństw
    def openMatrixFile(self):
        fileName = QtGui.QFileDialog.getOpenFileName(self, 'Open File', '.')
        if fileName != QString():
            (ret, matrix) = mp.read_matrix(str(fileName))
            if ret == mp.INVALID_MATRIX_FILE:
                QtGui.QMessageBox.warning(self, 'Matrix error', 
                          'Wrong file given.', 
                          QtGui.QMessageBox.Ok, QtGui.QMessageBox.Ok)
            elif ret == mp.INVALID_MATRIX:
                QtGui.QMessageBox.warning(self, 'Matrix error', 
                          'Given file does not contain correct matrix.', 
                          QtGui.QMessageBox.Ok, QtGui.QMessageBox.Ok)
            elif ret == mp.INVALID_MATRIX_DIM:
                QtGui.QMessageBox.warning(self, 'Matrix error', 
                          'Given matrix is has wrong dimension.', 
                          QtGui.QMessageBox.Ok, QtGui.QMessageBox.Ok)
            elif ret == mp.MATRIX_NOT_SYMMETRICAL:
                QtGui.QMessageBox.warning(self, 'Matrix error', 
                                          'Given matrix is not symmetrical.', 
                                          QtGui.QMessageBox.Ok, QtGui.QMessageBox.Ok)
            else:
                self.fillMatrix(matrix)
